﻿using Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using DrawableObjects.Actors;
using DrawableObjects.Actors.Weapons;
using DrawableObjects.Actors.Aircrafts;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using DrawableObjects.Actors.Aircrafts.Controller;
using Serialization.Script;
using Microsoft.Xna.Framework.Graphics;
using GlobalGameClasses;
using DrawableObjects.Actors.Projectiles;
using WorldView;

namespace InSovietRussiaProgrammTestsYou
{
    
    
    /// <summary>
    ///This is a test class for AchievementHandlerTest and is intended
    ///to contain all AchievementHandlerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class AchievementHandlerTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup()]
        public static void MyClassCleanup()
        {
            GlobalGameValues.Values.achievementsUnlocked = new List<Achievement>();
            GlobalGameValues.Values.content = new ContentCollection();
            GlobalGameValues.Values.difficulty = null;
            GlobalGameValues.Values.errorWriter = null;
            GlobalGameValues.Values.gameTime = new GameTime();
            GlobalGameValues.Values.GlobalStrings = new StringContainer();
            GlobalGameValues.Values.graphicsDevice = null;
            GlobalGameValues.Values.score = new InterfaceComponents.HUDWrapper<int>(new List<InterfaceComponents.HUDComponent>());
            GlobalGameValues.Values.soundPlayer = null;
            GlobalGameValues.Values.spriteBatch = null;
            GlobalGameValues.Values.volume_Music = 0;
            GlobalGameValues.Values.volume_soundEffect = 0;
        }
        //

        [TestInitialize()]
        public void MyTestInitialize()
        {
            System.Windows.Forms.Form form = new System.Windows.Forms.Form();
            form.Visible = false;
            form.ShowInTaskbar = false;
            PresentationParameters param = new PresentationParameters();
            param.DeviceWindowHandle = form.Handle;
            param.IsFullScreen = false;
            GraphicsDevice device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.HiDef, param);
            GlobalGameValues.Values.graphicsDevice = device;
            GlobalGameValues.Values.spriteBatch = new SpriteBatch(device);
            GlobalGameValues.Values.content.addTexture("smokeTexture", new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addTexture("fireTexture", new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addTexture("health", new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addContent("aircraft_enemy1", null, new Texture2D(device, 1, 1));
            GlobalGameValues.Values.GlobalStrings = new StringContainer();
            for (int i = 0; i < 10; i++)
            {
                GlobalGameValues.Values.GlobalStrings.addValue("TEST" + i, "ac" + i + "Name");
                GlobalGameValues.Values.GlobalStrings.addValue("TEST" + i, "ac" + i + "Dis");
            }

            GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked = new List<Achievement>();
        }
        //
        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked = new List<Achievement>();
        }
        //
        #endregion


        /// <summary>
        ///A test for OnDestroy
        ///</summary>
        [TestMethod()]
        public void OnDestroyTest()
        {
            int numberOfEnemies = 2; 
            string accountName = "Test"; 
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName); 
            Aircraft sender = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            sender.controller = new AIControlledAircraft_PathGuided(new Path());
            sender.owner = Owner.ENEMY;
            Aircraft destroyedBy = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            destroyedBy.owner = Owner.PLAYER;
            target.OnDestroy(sender, destroyedBy);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 0);
            target.OnDestroy(sender, destroyedBy);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 1);
        }

        /// <summary>
        ///A test for OnGameEnd
        ///</summary>
        [TestMethod()]
        public void OnGameEndTest_BossSpeed()
        {
            int numberOfEnemies = 0; 
            string accountName = string.Empty; 
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName);
            bool gameWon = true; 
            Aircraft testBoss = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            testBoss.controller = new AIControlledAircraft_Boss(null);
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(0), new TimeSpan(0));
            target.OnCreate(testBoss);
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(0, 0, 29), new TimeSpan(0, 0, 29));
            target.OnGameEnd(gameWon);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count >= 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 2);
        }

        /// <summary>
        ///A test for OnGameEnd
        ///</summary>
        [TestMethod()]
        public void OnGameEndTest_NoDamage()
        {
            int numberOfEnemies = 0;
            string accountName = string.Empty;
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName);
            bool gameWon = true;
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(0, 0, 31), new TimeSpan(0, 0, 31));
            target.OnGameEnd(gameWon);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count >= 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 0);

            GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked = new List<Achievement>();
            target = new AchievementHandler(numberOfEnemies, accountName);
            Aircraft player = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            player.controller = new PlayerControlledAircraft(null);
            Aircraft enemy = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            target.OnCollide(player, enemy);
            target.OnGameEnd(gameWon);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID != 0);
        }

        /// <summary>
        ///A test for OnGameEnd
        ///</summary>
        [TestMethod()]
        public void OnGameEndTest_NoDamageBoss()
        {
            int numberOfEnemies = 0;
            string accountName = string.Empty;
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName);
            bool gameWon = true;
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(0, 0, 31), new TimeSpan(0, 0, 31));
            target.OnGameEnd(gameWon);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 2);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 0);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[1].achievementID == 3);

            GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked = new List<Achievement>();
            target = new AchievementHandler(numberOfEnemies, accountName);

            Aircraft player = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            player.controller = new PlayerControlledAircraft(null);
            Aircraft testBoss = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            testBoss.controller = new AIControlledAircraft_Boss(null);

            target.OnCollide(player, testBoss);
            target.OnGameEnd(gameWon);

            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 3);
        }

        /// <summary>
        ///A test for OnGameEnd
        ///</summary>
        [TestMethod()]
        public void OnGameEndTest_DifficultyVeryHard()
        {
            int numberOfEnemies = 0;
            string accountName = string.Empty;
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName);
            bool gameWon = true;
            GlobalGameClasses.GlobalGameValues.Values.difficulty = Difficulty.DIFFICULTY_VERY_HARD;
            GlobalGameClasses.GlobalGameValues.Values.gameTime = new GameTime(new TimeSpan(0, 0, 31), new TimeSpan(0, 0, 31));
            target.OnGameEnd(gameWon);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 3);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[2].achievementID == 7);

            GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked = new List<Achievement>();
        }

        /// <summary>
        ///A test for OnUpgrade
        ///</summary>
        [TestMethod()]
        public void OnUpgradeTest()
        {
            int numberOfEnemies = 0; 
            string accountName = string.Empty; 
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName); 
            Actor sender = null; 
            Vector2 launchPoint = new Vector2(0,0);
            Weaponsystem upgraded = Weaponsystem.GET_WEAPON_PLAYER_LASER(new Vector2[]{launchPoint});
            upgraded.Upgrade();
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 0);
            upgraded.Upgrade();
            target.OnUpgrade(sender, upgraded);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 4);
            target.OnUpgrade(sender, upgraded);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 4);
            target.OnUpgrade(sender, upgraded);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 2);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[1].achievementID == 5);
        }

        /// <summary>
        ///A test for OnCreate
        ///</summary>
        [TestMethod()]
        public void OnCreateTest()
        {
            int numberOfEnemies = 0; 
            string accountName = string.Empty; 
            AchievementHandler_Accessor target = new AchievementHandler_Accessor(numberOfEnemies, accountName);
            Aircraft sender = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            sender.controller = new AIControlledAircraft_Boss(null);
            target.OnCreate(sender);
            Assert.IsTrue(target.bossActive);
        }

        /// <summary>
        ///A test for OnCollide
        ///</summary>
        [TestMethod()]
        public void OnCollideTest_DroneCollect()
        {
            int numberOfEnemies = 0; 
            string accountName = string.Empty;
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName); 
            GlobalGameClasses.GlobalGameValues.Values.difficulty = Difficulty.DIFFICULTY_VERY_HARD;
            Aircraft sender = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            World myWorld = new World(target, new GenericDrawableList(), new List<InterfaceComponents.InterfaceComponent>(), new LevelScript(new List<ScriptedEvent>()));
            AIControlledAircraft_Drone controller = new AIControlledAircraft_Drone(sender, sender);
            sender.world = myWorld;
            sender.controller = controller;
            controller.Update(DroneMode.COLLECT);
            Actor actor2 = WeaponUpgrade.GET_UPGRADEITEM(Weapon.WeaponType.Plasma);
            target.OnCollide(sender, actor2);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 0);
            target.OnCollide(sender, actor2);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 0);
            target.OnCollide(sender, actor2);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 8);
        }

        /// <summary>
        ///A test for OnCollide
        ///</summary>
        [TestMethod()]
        public void OnCollideTest_Regenerate()
        {
            int numberOfEnemies = 0; 
            string accountName = string.Empty;
            GlobalGameClasses.GlobalGameValues.Values.difficulty = Difficulty.DIFFICULTY_VERY_HARD;
            AchievementHandler target = new AchievementHandler(numberOfEnemies, accountName); 
            Aircraft sender = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            PlayerControlledAircraft controller = new PlayerControlledAircraft(sender);
            sender.controller = controller;
            HealingBeam actor2 = HealingBeam.GET_HEALING_BEAM_DRONE();
            float healing = actor2.getDamage();
            float counter = 0;
            while (counter > -500f)
            {
                target.OnCollide(actor2, sender);
                counter += healing;
            }
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked.Count == 1);
            Assert.IsTrue(GlobalGameClasses.GlobalGameValues.Values.achievementsUnlocked[0].achievementID == 6);
        }
    }
}
